/**
 * 
 */
package com.puneet.graphqueries.net;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;

import com.puneet.graphqueries.PartitionMessageHandler;
import com.puneet.graphqueries.yamlconfig.Partition;

/**
 * @author puneet
 * 
 */
public class TCPStatusSendReceive extends Thread {
	private PartitionMessageHandler partitionMessageHandler;
	private TCPMessageReceiver messageReceiver;
	private int delay = 1;
	private int period = 1;
	private boolean master = false;
	private List<Partition> partitions;

	public TCPStatusSendReceive(PartitionMessageHandler messageHandler, TCPMessageReceiver messageReceiver, int delay,
			boolean master, List<Partition> partitions) {
		this.partitions = partitions;
		this.partitionMessageHandler = messageHandler;
		this.messageReceiver = messageReceiver;
		this.delay = delay;
		this.master = master;
	}

	@Override
	public void run() {
		try {
			Thread listenerThread = new Thread() {
				public void run() {
					while (true) {
						try {
							ServerSocket ss = new ServerSocket(INetConstants.STATUS_SEND_RECEIVE_PORT);
							Socket socket = ss.accept();
							BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
							String s = br.readLine();
							if(s.startsWith("statuscheck")) {
								BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
								bw.write("status:" + (!messageReceiver.hasMessages()&&partitionMessageHandler.done()) + "\n");
								bw.close();
							}
							br.close();
							socket.close();
							ss.close();
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
			};
			listenerThread.start();
			
			if(master) {
				Thread.sleep(delay * 100);
				outerloop:while(true) {
					Thread.sleep(period * 100);
					boolean exit = true;
					System.out.println(partitions);
					for(Partition p:partitions) {
						try {
							Socket s = new Socket(p.getServer(),INetConstants.STATUS_SEND_RECEIVE_PORT);
							BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
							bw.write("statuscheck\n");
							bw.flush();
							BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
							String str = br.readLine();
							if(str.startsWith("status:")) {
								boolean thisNodeStatus = Boolean.parseBoolean(str.substring(7));
								if(!thisNodeStatus) {
									exit = false;
									continue outerloop;
								}
							}else {
								exit = false;
								continue outerloop;
							}
							bw.close();
							br.close();
							s.close();
						} catch (Exception e) {
							exit = false;
							e.printStackTrace();
						}
						
					}
					if(exit) {
						for(Partition partition:partitions) {
							Socket s = new Socket(partition.getServer(),INetConstants.MESSAGE_SEND_RECEIVE_PORT);
							BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
							bw.write("exit\n");
							bw.flush();
							bw.close();
							s.close();
						}
					}
					
					
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public PartitionMessageHandler getPartitionMessageHandler() {
		return partitionMessageHandler;
	}

	public void setPartitionMessageHandler(PartitionMessageHandler partitionMessageHandler) {
		this.partitionMessageHandler = partitionMessageHandler;
	}

	public TCPMessageReceiver getMessageReceiver() {
		return messageReceiver;
	}

	public void setMessageReceiver(TCPMessageReceiver messageReceiver) {
		this.messageReceiver = messageReceiver;
	}

	public int getDelay() {
		return delay;
	}

	public void setDelay(int delay) {
		this.delay = delay;
	}

	public int getPeriod() {
		return period;
	}

	public void setPeriod(int period) {
		this.period = period;
	}

	public boolean isMaster() {
		return master;
	}

	public void setMaster(boolean master) {
		this.master = master;
	}

}
